/*********************************************************
          File Name:instantiation.cpp
          Author: Abby Cin
          Mail: abbytsing@gmail.com
          Created Time: Mon 15 Feb 2016 09:09:19 PM CST
**********************************************************/

#include <iostream>

class X
{
    public:
        int x, y;
    public:
        X() = default;
        X(const int &lhs, const int &rhs):
            x(lhs), y(rhs){}
        
        X(const X &o) = delete;
        /*{
            x = o.x;
            y = o.y;
        }*/
        ~X(){}

        void show() const
        {
            std::cout << x << "\t" << y << std::endl;
        }
};

template<typename T>
void exchange(T &lhs, T &rhs)
{
    T tmp;
    tmp = lhs;
    lhs = rhs;
    rhs = tmp;
}

template<> void exchange(X &lhs, X &rhs)
{
    int tmp;
    tmp = lhs.x;
    lhs.x = rhs.x;
    rhs.x = tmp;
    tmp = lhs.y;
    lhs.y = rhs.y;
    rhs.y = tmp;
    std::cout << "specialization" << std::endl;
}

int main()
{
    int x = 0, y = 1;
    std::string s1{"lhs"}, s2{"rhs"};
    X obj1(1, 2), obj2(2, 1);

    // implicit instantiation
    exchange(x, y);

    // explicit instantiation
    exchange<std::string>(s1, s2);

    // explicit specailization
    obj1.show();
    exchange(obj1, obj2);
    obj1.show();

    //---------------------------
    obj1.show();
    exchange<X>(obj1, obj2);
    obj1.show();

    return 0;
}
